
package com.trydofor.id.ware;

import java.util.Arrays;
import java.util.HashSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.Resource;

/**
 * @author : Shi Rongjiu (www.trydofor.com)
 */
public class SpringFactory implements WareFactory {
    
    private final Logger                     logger = LoggerFactory.getLogger(SpringFactory.class);
    private final DefaultListableBeanFactory factory;
    
    /**
     * constructor
     */
    public SpringFactory() {
        factory = new DefaultListableBeanFactory();
    }
    
    /**
     * register beans by xml config file
     * 
     * @param src the resource of config file
     * @return the count of beans
     */
    public int registerXmlConfBeans(Resource src) {
        XmlBeanDefinitionReader rd = new XmlBeanDefinitionReader(factory);
        return rd.loadBeanDefinitions(src);
    }
    
    /**
     * Register the given existing object as singleton in the bean registry,
     * under the given bean name.
     * 
     * @param name the name of the bean
     * @param inst the existing singleton object
     * @see DefaultListableBeanFactory#registerSingleton(String, Object)
     */
    public void registerSingleton(String name, Object inst) {
        factory.registerSingleton(name, inst);
    }
    
    /**
     * Return the names of all beans defined in this factory.
     * 
     * @see DefaultListableBeanFactory#getBeanDefinitionNames()
     * @see DefaultListableBeanFactory#getSingletonNames()
     * @return the names of all
     */
    public String[] getAllBeanNames() {
        String[] sg = factory.getSingletonNames();
        String[] bn = factory.getBeanDefinitionNames();
        HashSet<String> set = new HashSet<String>();
        for (String s : sg) {
            set.add(s);
        }
        for (String s : bn) {
            set.add(s);
        }
        String[] r = new String[set.size()];
        set.toArray(r);
        Arrays.sort(r);
        return r;
    }
    
    /**
     * remove bean by the name
     * 
     * @param name bean name
     * @return true if removed
     * @see DefaultListableBeanFactory#removeBeanDefinition(String)
     */
    public boolean removeBean(String name) {
        try {
            factory.removeBeanDefinition(name);
        }
        catch (NoSuchBeanDefinitionException e) {
            logger.error("can not remove bean," + name, e);
            return false;
        }
        return true;
    }
    
    /**
     * {@inheritDoc}
     */
    public Object getInstance(String name) {
        try {
            return factory.getBean(name);
        }
        catch (BeansException e) {
            logger.error("can not get bean," + name, e);
            return null;
        }
    }
}
